IndexedDB 操作类
/**
* @method Promise createStore()
* @method Promise save({data:data} ,[primary])
* @method Promise get()
* @method Promise find(primary)
* @method Promise update({data:data} ,primary)
* @method Promise destroy(paimary)
* @method Promise clear()
*
* @example
* let db = new DB()
* db.setVersion(版本 ,默认为2)
* db.setPrimaryKey('主键名')
* db.setStore('存储库名')
* db.setDatabase('数据库名')
* // 链接存储库
* await db.createStore()
* // 添加或更新数据
* await db.save({data:data} ,[primary])
* // 获取全部数据
* await db.get()
* // 获取一条数据
* await db.find(primary)
* // 依据主键更新
* await db.update({data:data} ,primary)
* // 依据主键删除
* await db.destroy(paimary)
* // 清空全表
* await db.clear()
* @constructor
*/
function DB() {
// 实例
this.version = 2
this.database = null
this.table = null
this.primaryKey = 'key'
// 创建数据库和存储空间(表)
this.createStore = async (store = null) => {
if (store !== null) {
this.setStore(store)
}
if (this.supportIndexDB()) {
throw new Error('浏览器不支持 IndexDB 请更换浏览器')
}
// 连接数据库
let conn = indexedDB.open(this.database, this.version)
conn.onerror = event => {
throw new Error('不能打开数据库 CODE: ' + event.target.errorCode)
}
conn.onupgradeneeded = event => {
this.instance = event.target.result
// 存在则删除
if (this.instance.objectStoreNames.contains(this.table)) {
this.instance.deleteObjectStore(this.table)
}
// 创建表
this.instance.createObjectStore(this.table, {keyPath: this.primaryKey})
}
// 返回资源
return new Promise((resolve, reject) => conn.onsuccess = event => {
this.instance = event.target.result
resolve(this.instance)
})
}
/**
* 获取所有值
* @returns {Promise<any>}
*/
this.get = async () => {
let request = this.getTransaction().getAll()
return new Promise((resolve, reject) => request.onsuccess = () => resolve(request.result))
}
/**
* 根据主键查找
* @param primary
* @returns {Promise<any>}
*/
this.find = async primary => {
if (!primary) {
throw new Error('主键不能为空')
}
let request = this.getTransaction().get(primary)
return new Promise((resolve, reject) => request.onsuccess = () => resolve(request.result))
}
/**
* 插入或更新数据
* @param data
* @param primary
*/
this.save = (data, primary) => {
// 如果数据中的第一级含有名为keyPath的key , 那么就不能通过第二个参数指定 key , 即使 key = primary
// 例如 {id:1,app:[],b:12} ,那么1就会被自动设为主键,无法再使用primary指定,但是更新可以
let request
// 如果存在不存在ID , 那么就使用指定的主键创建数据,存在就用默认主键
if (typeof data[this.primaryKey] === 'undefined') {
if (typeof primary === 'undefined') {
throw new Error('数据不包含默认主键,且没有显式声明主键')
}
request = this.getTransaction().add(data)
} else {
request = this.getTransaction().add(data, primary)
}
return new Promise((resolve, reject) => {
request.onsuccess = () => {
resolve(request.result)
}
request.onerror = () => {
resolve(this.update(data, primary))
}
})
}
/**
* 依据主键更新数据
* @param data
* @param primary
*/
this.update = async (data, primary) => {
//此处须显式声明事物
let request = this.getTransaction().put(data, primary)
return new Promise((resolve, reject) => {
request.onsuccess = () => {
resolve(request.result)
}
request.onerror = () => {
reject(event.target.error.code, event.target.error.message)
}
})
}
/**
* 根据主键删除
* @param primary
* @returns {Promise<any>}
*/
this.destroy = async primary => {
let request = this.getTransaction().delete(primary)
return new Promise((resolve, reject) => request.onsuccess = e => resolve(e.target))
}
/**
* 清空全表
* @returns {Promise<any>}
*/
this.clear = async () => {
let request = this.getTransaction().clear()
return new Promise((resolve, reject) => request.onsuccess = () => resolve(request))
}
/**
* 获取一个事务
* @returns {IDBObjectStore}
*/
this.getTransaction = () => {
return this.instance.transaction(this.table, 'readwrite').objectStore(this.table)
}
/**
* 删除数据库
* @returns {Promise<any>}
*/
this.deleteDatabase = () => {
let deleted = window.indexedDB.deleteDatabase(this.database)
return new Promise((resolve, reject) => deleted.onsuccess = () => resolve('Database deleted successfully'))
}
/**
* 判断是否支持IndexDB
* @returns {boolean}
*/
this.supportIndexDB = () => {
return !window.indexedDB
}
this.closeDB = () => {
this.instance.close()
return this
}
this.setDatabase = db => {
this.database = db
return this
}
this.setStore = table => {
this.table = table
return this
}
this.setPrimaryKey = primaryKey => {
this.primaryKey = primaryKey
return this
}
this.setVersion = version => {
this.version = version
return this
}
}